/***************************************************************************************************
 *Copyright(C),2010-2016,Sumscope
 *FileName	:  JsonWriter.h
 *Author	:  scofined.qi
 *Version	:  1.0
 *Date		:  2016/09/12
 *Desc		:  //用于主要说明此程序文件完成的主要功能
 *Relation :
 *Others	:  //其他内容说明
 *Function :  //主要函数列表，每条记录应包含函数名及功能简要说明
 *History	:
 * //修改历史记录列表，每条修改记录应包含修改日期、修改者及修改内容简介
 ***************************************************************************************************/
#ifndef JSONWRITER_H_EC400FCA_F023_453A_B43A_A285B2F8442A
#define JSONWRITER_H_EC400FCA_F023_453A_B43A_A285B2F8442A

#include <core/Utility.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "simple_array.h"

namespace qb {
namespace base {
class JsonWriter {  // 将json转化为字符串
 public:
  typedef char Element;
  typedef qb::base::SimpleArray<Element> Buffer;
  typedef JsonWriter Writer;

 protected:
  bool m_finished;
  bool m_rootmap;
  bool m_rootlist;
  bool m_format;
  int m_count;  // 等级
  int m_level;
  Buffer* m_buffer;

 public:
  class JsonWriterMap;
  class JsonWriterList {
    Writer* m_writer;
    int m_count;

   public:
    JsonWriterList(Writer* writer) : m_writer(writer), m_count(0) {
      if (writer) writer->SetLevel(writer->GetLevel() + 1);
    }
    ~JsonWriterList() { End(); }
    void End();

    Writer* AddMap() {
      AddHead();
      return m_writer;
    }
    Writer* AddList() {
      AddHead();
      return m_writer;
    }
    void AddString(const Element* str, int len = 0) {
      AddHead();
      m_writer->AddJsonString(str, len);
    }
    void AddBool(bool bvalue) {
      AddHead();
      m_writer->AddBool(bvalue);
    }
    void AddInt(int ivalue) {
      AddHead();
      m_writer->AddInt(ivalue);
    }
    void AddUint(unsigned int uvalue) {
      AddHead();
      m_writer->AddUint(uvalue);
    }
    void AddUint64(unsigned long long u64) {
      AddHead();
      m_writer->AddUint64(u64);
    }
    void AddInt64(long long ivalue) {
      AddHead();
      m_writer->AddInt64(ivalue);
    }
    void AddDouble(double dvalue) {
      AddHead();
      m_writer->AddDouble(dvalue);
    }
    void AddHead();
  };
  class JsonWriterMap {
    Writer* m_writer;
    int m_count;

   public:
    JsonWriterMap(Writer* writer) : m_writer(writer), m_count(0) {
      if (writer) writer->SetLevel(writer->GetLevel() + 1);
    }
    ~JsonWriterMap() { End(); }
    void End();
    Writer* AddMap(const Element* name) {
      AddHeadAndName(name);
      return m_writer;
    }
    Writer* AddList(const Element* name) {
      AddHeadAndName(name);
      return m_writer;
    }
    void AddString(const Element* name, const Element* str, int len = 0) {
      AddHeadAndName(name);
      m_writer->AddJsonString(str, len);
    }
    void AddBool(const Element* name, bool bvalue) {
      AddHeadAndName(name);
      m_writer->AddBool(bvalue);
    }
    void AddInt(const Element* name, int ivalue, int len = 0) {
      AddHeadAndName(name, len);
      m_writer->AddInt(ivalue);
    }
    void AddUint(const Element* name, unsigned int uvalue) {
      AddHeadAndName(name);
      m_writer->AddUint(uvalue);
    }
    void AddUint64(const Element* name, unsigned long long u64) {
      AddHeadAndName(name);
      m_writer->AddUint64(u64);
    }
    void AddInt64(const Element* name, long long ivalue) {
      AddHeadAndName(name);
      m_writer->AddInt64(ivalue);
    }
    void AddDouble(const Element* name, double dvalue) {
      AddHeadAndName(name);
      m_writer->AddDouble(dvalue);
    }
    void AddHead();
    void AddHeadAndName(const Element* name, int len = 0);
  };

 private:
  JsonWriter(const JsonWriter& jw){};
  JsonWriter& operator=(const JsonWriter& jw) { return *this; }

 public:
  typedef JsonWriterList List;
  typedef JsonWriterMap Map;
  JsonWriter(int initCapcity = 0);
  ~JsonWriter();
  void Reset();
  int GetCapcity() const;
  int GetBytes() const { return m_buffer ? m_buffer->size() : 0; }
  void Start(int capcity);
  void SeekPos(int pos);
  void SetFormat() { m_format = true; }
  const Element* c_str();
  int size();

  Writer* AddRootList() {
    m_rootlist = true;
    m_rootmap = false;
    return this;
  }
  Writer* AddRootMap() {
    m_rootlist = false;
    m_rootmap = true;
    return this;
  }
  Writer* AddMap(const Element* name);
  Writer* AddList(const Element* name);

 protected:
  int GetLevel() const { return m_level; }
  void SetLevel(int level) { m_level = level; }
  void AddNewLine();
  void AddName(const Element* name, int len = 0);
  void AddJsonString(const Element* str, int len = 0);
  void AddString(const Element* str, int len = 0);
  void AddBool(bool bvalue) {
    AddString(bvalue ? "true" : "false", bvalue ? 4 : 5);
  }
  void AddInt(int ivalue) {
    Element buf[64] = {0};
    FMTBUF(buf, "%d", ivalue);
    AddString(buf);
  }
  void AddUint(unsigned int uvalue) {
    Element buf[64] = {0};
    int len = FMTBUF(buf, "%u", uvalue);
    AddString(buf, len);
  }
  void AddUint64(unsigned long long u64) {
    Element buf[64] = {0};
    FMTBUF(buf, "%llu", u64);
    AddString(buf);
  }
  void AddInt64(long long ivalue) {
    Element buf[64] = {0};
    FMTBUF(buf, "%lld", ivalue);
    AddString(buf);
  }
  void AddDouble(double dvalue) {
    Element buf[64] = {0};
    int len = FMTBUF(buf, "%f", dvalue);
    AddString(buf, len);
  }
};
}  // namespace base
}  // namespace qb
#endif
